<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>PDF 坐标框选验证 Demo</title>
    <style>
        .container {
            max-width: 100%;
            margin: 20px auto;
            padding: 20px;
        }
        .input-group {
            margin-bottom: 15px;
        }
        input {
            width: 100px;
            margin-right: 10px;
            padding: 5px;
        }
        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            cursor: pointer;
        }
        button:hover {
            background: #0056b3;
        }
        #pdf-container {
            position: relative;
            margin-top: 20px;
        }
        #pdf-canvas {
            border: 1px solid #ddd;
        }
        #overlay-canvas {
            position: absolute;
            top: 0;
            left: 0;
            pointer-events: none; /* 允许点击下方 Canvas */
        }
        .error {
            color: red;
            margin-top: 10px;
        }
        
    </style>
</head>
<body>
    <div class="container">
        <h2>PDF 坐标框选验证</h2>
        
        <!-- 文件上传 -->
        <div class="input-group">
            <input type="file" id="pdf-file" accept=".pdf">
            <p>提示：上传后输入 PDF 页面中文字的坐标（x, y, w, h，单位：pt）</p >
        </div>

        <!-- 坐标输入 -->
        <div class="input-group">
            <label>X (pt): </label><input type="number" id="x-input" step="1">
            <label>Y (pt): </label><input type="number" id="y-input" step="1">
            <label>宽度 (pt): </label><input type="number" id="w-input" step="1">
            <label>高度 (pt): </label><input type="number" id="h-input" step="1">
            <button onclick="highlightText()">绘制框选</button>
        </div>

        <!-- 错误提示 -->
        <div id="error-msg" class="error"></div>

        <!-- PDF 渲染容器（含 Canvas 和覆盖层） -->
        <div id="pdf-container"></div>
    </div>

    <!-- 引入 PDF.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script>
    <script>
        let pdfDoc = null; // 存储 PDF 文档对象
        let currentPage = 1; // 当前渲染页（默认第一页）
        let currentPageRendered = false; // 标记当前页是否已渲染

        // 监听文件上传
        document.getElementById('pdf-file').addEventListener('change', async (e) => {
            const file = e.target.files[0];
            if (!file) return;

            // 清空错误提示和容器
            document.getElementById('error-msg').textContent = '';
            document.getElementById('pdf-container').innerHTML = '';

            try {
                // 加载 PDF 文件
                const reader = new FileReader();
                reader.onload = async (event) => {
                    const pdfData = new Uint8Array(event.target.result);
                    pdfDoc = await pdfjsLib.getDocument({ data: pdfData }).promise;
                    
                    // 渲染第一页
                    await renderPage(currentPage);
                    currentPageRendered = true;
                };
                reader.readAsArrayBuffer(file);
            } catch (err) {
                document.getElementById('error-msg').textContent = `加载 PDF 失败：${err.message}`;
            }
        });

        // 渲染 PDF 单页到 Canvas
        async function renderPage(pageNum) {
            if (!pdfDoc) return;

            const page = await pdfDoc.getPage(pageNum);
            const viewport = page.getViewport({ scale: 1.0 }); // 初始缩放 1:1（1pt=1px）

            // 创建 Canvas 容器
            const container = document.getElementById('pdf-container');
            const canvas = document.createElement('canvas');
            canvas.id = 'pdf-canvas';
            container.appendChild(canvas);

            // 设置 Canvas 尺寸匹配 PDF 页面（pt → px，1:1 缩放）
            canvas.width = viewport.width;
            canvas.height = viewport.height;

            // 渲染 PDF 内容到 Canvas
            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            }).promise;

            // 创建覆盖 Canvas（用于绘制框选）
            const overlayCanvas = document.createElement('canvas');
            overlayCanvas.id = 'overlay-canvas';
            overlayCanvas.width = canvas.width;
            overlayCanvas.height = canvas.height;
            container.appendChild(overlayCanvas);
        }

        // 绘制框选（关键修改）
    function highlightText() {
        const errorMsg = document.getElementById('error-msg');
        if (!pdfDoc || !currentPageRendered) {
            errorMsg.textContent = '请先上传 PDF 文件！';
            return;
        }

        // 获取输入的坐标
        const x = parseFloat(document.getElementById('x-input').value);
        const y = parseFloat(document.getElementById('y-input').value);
        const w = parseFloat(document.getElementById('w-input').value);
        const h = parseFloat(document.getElementById('h-input').value);

        // 验证输入有效性
        if ([x, y, w, h].some(isNaN)) {
            errorMsg.textContent = '请输入有效的数字坐标！';
            return;
        }
        if (x < 0 || y < 0 || w <= 0 || h <= 0) {
            errorMsg.textContent = '坐标或尺寸不能为负数或零！';
            return;
        }

        // 获取覆盖 Canvas 和页面实际高度（已考虑旋转）
        const overlayCanvas = document.getElementById('overlay-canvas');
        const ctx = overlayCanvas.getContext('2d');
        
        // 清空之前的绘制
        ctx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);

        // 设置荧光笔样式（黄色透明填充 + 边缘阴影）
        ctx.fillStyle = 'rgba(255, 255, 0, 0.3)'; // 黄色，30% 透明度
        ctx.strokeStyle = 'rgba(255, 200, 0, 0.8)'; // 深黄边框（可选）
        //ctx.lineWidth = 1; // 边框宽度（可选）
        ctx.shadowColor = 'rgba(255, 255, 0, 0.5)'; // 阴影颜色
        ctx.shadowBlur = 5; // 阴影模糊半径（可选）

        // 计算 Canvas 中的 Y 坐标（修正偏移问题）
        const imgY = y - h;

        // 绘制填充矩形（荧光笔主体）
        ctx.fillRect(x, imgY, w, h);

        // 绘制边框（可选，增强边缘）
        // ctx.strokeRect(x, imgY, w, h);

        errorMsg.textContent = '';
    }
    </script>
</body>
</html>
